#include "websocketserver.h"
#include "application_manager.h"
#include <QDebug>
#include <QDateTime>
#include <QBuffer>
#include <QCryptographicHash>
#include <QNetworkInterface>
#include <QHostAddress>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QTimer>
#include <QMutexLocker>
#include <QImage>
#include <QByteArray>
#include <QString>
#include <QList>

WebSocketServer::WebSocketServer(QObject *parent)
    : QObject(parent)
    , m_server(nullptr)
    , m_applicationManager(nullptr)
    , m_applicationListTimer(nullptr)
    , m_isRunning(false)
    , m_frameIndex(0)
    , m_lastFrameTime(0)
    , m_targetFps(30)
    , m_frameIntervalMs(1000 / 30)
{
    m_server = new QTcpServer(this);
    connect(m_server, &QTcpServer::newConnection, this, &WebSocketServer::onNewConnection);
    
    // 创建应用程序列表广播定时器
    m_applicationListTimer = new QTimer(this);
    connect(m_applicationListTimer, &QTimer::timeout, this, &WebSocketServer::onApplicationListTimer);
}

WebSocketServer::~WebSocketServer()
{
    stopServer();
}

bool WebSocketServer::startServer(quint16 port)
{
    if (m_isRunning) {
        qWarning() << "WebSocket服务器已经在运行";
        return true;
    }
    
    if (!m_server->listen(QHostAddress::Any, port)) {
        qCritical() << "无法启动WebSocket服务器:" << m_server->errorString();
        return false;
    }
    
    m_isRunning = true;
    qDebug() << QString("WebSocket服务器已启动，监听端口: %1").arg(port);
    
    // 启动应用程序列表广播
    m_applicationListTimer->start(5000); // 每5秒广播一次
    
    return true;
}

void WebSocketServer::stopServer()
{
    if (!m_isRunning) {
        return;
    }
    
    qDebug() << "正在停止WebSocket服务器...";
    m_isRunning = false;
    
    // 停止定时器
    if (m_applicationListTimer) {
        m_applicationListTimer->stop();
    }
    
    // 关闭所有客户端连接
    QMutexLocker locker(&m_clientsMutex);
    for (QTcpSocket *client : m_clients) {
        client->disconnectFromHost();
        client->deleteLater();
    }
    m_clients.clear();
    locker.unlock();
    
    // 停止服务器
    if (m_server) {
        m_server->close();
    }
    
    qDebug() << "WebSocket服务器已停止";
}

bool WebSocketServer::isServerRunning() const
{
    return m_isRunning && m_server && m_server->isListening();
}

int WebSocketServer::getClientCount() const
{
    return m_clients.size();
}

void WebSocketServer::broadcastFrame(const QImage &image)
{
    if (!m_isRunning || image.isNull()) {
        return;
    }
    
    // 帧率控制
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    if (currentTime - m_lastFrameTime < m_frameIntervalMs) {
        return; // 跳过这一帧
    }
    m_lastFrameTime = currentTime;
    
    QJsonObject frameMessage = createFrameMessage(image, currentTime, m_frameIndex++);
    
    QMutexLocker locker(&m_clientsMutex);
    QList<QTcpSocket*> disconnectedClients;
    
    for (QTcpSocket *client : m_clients) {
        if (client->state() == QAbstractSocket::ConnectedState) {
            try {
                sendTextMessage(client, frameMessage);
            } catch (...) {
                disconnectedClients.append(client);
            }
        } else {
            disconnectedClients.append(client);
        }
    }
    
    // 清理断开的客户端
    for (QTcpSocket *client : disconnectedClients) {
        m_clients.removeAll(client);
        client->deleteLater();
    }
}

void WebSocketServer::broadcastFrameAsync(const QImage &image)
{
    if (!m_isRunning || image.isNull()) {
        return;
    }
    
    // 帧率控制
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    if (currentTime - m_lastFrameTime < m_frameIntervalMs) {
        return; // 跳过这一帧
    }
    m_lastFrameTime = currentTime;
    
    // 使用QTimer::singleShot异步处理图像编码和发送
    QTimer::singleShot(0, [this, image, currentTime]() {
        try {
            QJsonObject frameMessage = createFrameMessage(image, currentTime, m_frameIndex++);
            
            QMutexLocker locker(&m_clientsMutex);
            QList<QTcpSocket*> disconnectedClients;
            
            for (QTcpSocket *client : m_clients) {
                if (client->state() == QAbstractSocket::ConnectedState) {
                    try {
                        sendTextMessage(client, frameMessage);
                    } catch (...) {
                        disconnectedClients.append(client);
                    }
                } else {
                    disconnectedClients.append(client);
                }
            }
            
            // 清理断开的客户端
            for (QTcpSocket *client : disconnectedClients) {
                m_clients.removeAll(client);
                client->deleteLater();
            }
        } catch (const std::exception &e) {
            qDebug() << QString("异步广播帧失败: %1").arg(e.what());
        }
    });
}

void WebSocketServer::broadcastAudio(const QByteArray &audioData)
{
    if (!m_isRunning || audioData.isEmpty()) {
        return;
    }
    
    QJsonObject audioMessage = createAudioMessage(audioData);
    
    QMutexLocker locker(&m_clientsMutex);
    QList<QTcpSocket*> disconnectedClients;
    
    for (QTcpSocket *client : m_clients) {
        if (client->state() == QAbstractSocket::ConnectedState) {
            try {
                sendTextMessage(client, audioMessage);
            } catch (...) {
                disconnectedClients.append(client);
            }
        } else {
            disconnectedClients.append(client);
        }
    }
    
    // 清理断开的客户端
    for (QTcpSocket *client : disconnectedClients) {
        m_clients.removeAll(client);
        client->deleteLater();
    }
}

void WebSocketServer::broadcastMessage(const QJsonObject &message)
{
    if (!m_isRunning) {
        return;
    }
    
    QMutexLocker locker(&m_clientsMutex);
    QList<QTcpSocket*> disconnectedClients;
    
    for (QTcpSocket *client : m_clients) {
        if (client->state() == QAbstractSocket::ConnectedState) {
            try {
                sendTextMessage(client, message);
            } catch (...) {
                disconnectedClients.append(client);
            }
        } else {
            disconnectedClients.append(client);
        }
    }
    
    // 清理断开的客户端
    for (QTcpSocket *client : disconnectedClients) {
        m_clients.removeAll(client);
        client->deleteLater();
    }
}

void WebSocketServer::setApplicationManager(ApplicationManager *manager)
{
    m_applicationManager = manager;
}

void WebSocketServer::onNewConnection()
{
    QTcpSocket *client = m_server->nextPendingConnection();
    if (!client) {
        return;
    }
    
    connect(client, &QTcpSocket::disconnected, this, &WebSocketServer::onClientDisconnected);
    connect(client, &QTcpSocket::readyRead, this, &WebSocketServer::onClientDataReady);
    
    qDebug() << "新客户端连接:" << client->peerAddress().toString();
}

void WebSocketServer::onClientDisconnected()
{
    QTcpSocket *client = qobject_cast<QTcpSocket*>(sender());
    if (!client) {
        return;
    }
    
    QMutexLocker locker(&m_clientsMutex);
    m_clients.removeAll(client);
    locker.unlock();
    
    // 清理客户端缓冲区
    {
        QMutexLocker bufferLocker(&m_buffersMutex);
        m_clientBuffers.remove(client);
    }
    
    qDebug() << "客户端断开连接:" << client->peerAddress().toString();
    emit clientDisconnected(client);
    client->deleteLater();
}

void WebSocketServer::onClientDataReady()
{
    QTcpSocket *client = qobject_cast<QTcpSocket*>(sender());
    if (!client) {
        return;
    }
    
    QByteArray newData = client->readAll();
    if (newData.isEmpty()) {
        return;
    }
    
    // 将新数据添加到客户端缓冲区
    {
        QMutexLocker locker(&m_buffersMutex);
        m_clientBuffers[client] += newData;
    }
    
    QByteArray fullData;
    {
        QMutexLocker locker(&m_buffersMutex);
        fullData = m_clientBuffers[client];
    }
    
    // 检查是否是WebSocket握手
    if (fullData.startsWith("GET ")) {
        // 检查是否包含完整的HTTP头（以\r\n\r\n结尾）
        if (fullData.contains("\r\n\r\n")) {
            if (performHandshake(client, fullData)) {
                QMutexLocker locker(&m_clientsMutex);
                m_clients.append(client);
                locker.unlock();
                
                // 清理缓冲区
                {
                    QMutexLocker bufferLocker(&m_buffersMutex);
                    m_clientBuffers.remove(client);
                }
                
                qDebug() << "WebSocket握手成功:" << client->peerAddress().toString();
                emit clientConnected(client);
                
                // 发送连接确认消息
                QJsonObject message;
                message["type"] = "connection";
                message["message"] = "连接成功";
                message["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);
                sendTextMessage(client, message);
            } else {
                qWarning() << "WebSocket握手失败:" << client->peerAddress().toString();
                client->disconnectFromHost();
            }
        }
        // 如果握手数据不完整，等待更多数据
    } else {
        // 处理WebSocket帧
        handleWebSocketFrame(client, fullData);
    }
}

void WebSocketServer::onApplicationListTimer()
{
    if (!m_applicationManager || !m_isRunning) {
        return;
    }
    
    QStringList applications = m_applicationManager->getApplicationList();
    
    QJsonObject message;
    message["type"] = "applications_list";
    message["data"] = QJsonArray::fromStringList(applications);
    message["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);
    
    broadcastMessage(message);
}

bool WebSocketServer::performHandshake(QTcpSocket *client, const QByteArray &requestData)
{
    QString requestStr = QString::fromUtf8(requestData);
    
    qDebug() << "收到WebSocket握手请求:";
    qDebug() << requestStr;
    
    if (!requestStr.startsWith("GET ")) {
        qDebug() << "请求不是以GET开头";
        return false;
    }
    
    // 提取Sec-WebSocket-Key
    QString key;
    QStringList lines = requestStr.split('\n');
    for (const QString &line : lines) {
        if (line.startsWith("Sec-WebSocket-Key:")) {
            QStringList parts = line.split(':');
            if (parts.size() >= 2) {
                key = parts[1].trimmed();
            }
            break;
        }
    }
    
    qDebug() << "提取到的WebSocket Key:" << key;
    
    if (key.isEmpty()) {
        qDebug() << "未找到Sec-WebSocket-Key";
        return false;
    }
    
    // 生成Sec-WebSocket-Accept
    QByteArray acceptKey = generateWebSocketKey(key.toUtf8());
    qDebug() << "生成的Accept Key:" << QString::fromUtf8(acceptKey);
    
    // 发送握手响应
    QString response = QString(
        "HTTP/1.1 101 Switching Protocols\r\n"
        "Upgrade: websocket\r\n"
        "Connection: Upgrade\r\n"
        "Sec-WebSocket-Accept: %1\r\n"
        "\r\n"
    ).arg(QString::fromUtf8(acceptKey));
    
    qDebug() << "发送握手响应:";
    qDebug() << response;
    
    client->write(response.toUtf8());
    return true;
}

void WebSocketServer::handleWebSocketFrame(QTcpSocket *client, const QByteArray &data)
{
    if (data.size() < 2) {
        return;
    }
    
    // 解析WebSocket帧头
    quint8 firstByte = static_cast<quint8>(data[0]);
    quint8 secondByte = static_cast<quint8>(data[1]);
    
    bool fin = (firstByte & 0x80) != 0;
    quint8 opcode = firstByte & 0x0F;
    bool masked = (secondByte & 0x80) != 0;
    quint64 payloadLength = secondByte & 0x7F;
    
    // 处理扩展长度
    int headerSize = 2;
    if (payloadLength == 126) {
        if (data.size() < 4) return;
        payloadLength = qFromBigEndian<quint16>(reinterpret_cast<const uchar*>(data.data() + 2));
        headerSize = 4;
    } else if (payloadLength == 127) {
        if (data.size() < 10) return;
        payloadLength = qFromBigEndian<quint64>(reinterpret_cast<const uchar*>(data.data() + 2));
        headerSize = 10;
    }
    
    // 读取掩码（如果存在）
    QByteArray mask;
    if (masked) {
        if (data.size() < headerSize + 4) return;
        mask = data.mid(headerSize, 4);
        headerSize += 4;
    }
    
    // 读取负载
    if (data.size() < headerSize + static_cast<int>(payloadLength)) {
        return; // 数据不完整
    }
    
    QByteArray payload = data.mid(headerSize, static_cast<int>(payloadLength));
    
    // 应用掩码
    if (masked && !mask.isEmpty()) {
        payload = unmaskData(payload, mask);
    }
    
    // 处理不同类型的帧
    switch (opcode) {
    case 0x1: // 文本帧
        try {
            QJsonDocument doc = QJsonDocument::fromJson(payload);
            if (doc.isObject()) {
                handleClientMessage(client, doc.object());
            }
        } catch (...) {
            qWarning() << "解析JSON消息失败";
        }
        break;
        
    case 0x8: // 关闭帧
        client->disconnectFromHost();
        break;
        
    case 0x9: // Ping帧
        sendWebSocketFrame(client, QByteArray(), 0xA); // Pong
        break;
        
    case 0xA: // Pong帧
        // 处理Pong响应
        break;
        
    default:
        qWarning() << "未知的WebSocket操作码:" << opcode;
        break;
    }
}

void WebSocketServer::sendWebSocketFrame(QTcpSocket *client, const QByteArray &data, quint8 opcode)
{
    QByteArray frame;
    
    // 第一个字节：FIN + RSV + Opcode
    frame.append(static_cast<char>(0x80 | opcode));
    
    // 第二个字节：MASK + Payload Length
    quint64 payloadLength = data.size();
    if (payloadLength < 126) {
        frame.append(static_cast<char>(payloadLength));
    } else if (payloadLength < 65536) {
        frame.append(static_cast<char>(126));
        frame.append(static_cast<char>((payloadLength >> 8) & 0xFF));
        frame.append(static_cast<char>(payloadLength & 0xFF));
    } else {
        frame.append(static_cast<char>(127));
        for (int i = 7; i >= 0; --i) {
            frame.append(static_cast<char>((payloadLength >> (i * 8)) & 0xFF));
        }
    }
    
    // 添加负载
    frame.append(data);
    
    client->write(frame);
}

void WebSocketServer::sendTextMessage(QTcpSocket *client, const QJsonObject &message)
{
    QJsonDocument doc(message);
    QByteArray data = doc.toJson(QJsonDocument::Compact);
    sendWebSocketFrame(client, data, 0x81); // 文本帧
}

void WebSocketServer::sendBinaryMessage(QTcpSocket *client, const QByteArray &data)
{
    sendWebSocketFrame(client, data, 0x82); // 二进制帧
}

void WebSocketServer::handleClientMessage(QTcpSocket *client, const QJsonObject &message)
{
    QString type = message["type"].toString();
    
    if (type == "ping") {
        handlePing(client);
    } else if (type == "pong") {
        handlePong(client);
    } else if (type == "request_frame") {
        handleFrameRequest(client);
    } else if (type == "request_audio") {
        handleAudioRequest(client);
    } else if (type == "launch_app") {
        handleLaunchApp(client, message);
    } else {
        qDebug() << "收到未知消息类型:" << type;
        emit messageReceived(client, message);
    }
}

void WebSocketServer::handlePing(QTcpSocket *client)
{
    QJsonObject response;
    response["type"] = "pong";
    response["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);
    sendTextMessage(client, response);
}

void WebSocketServer::handlePong(QTcpSocket *client)
{
    Q_UNUSED(client)
    // 处理Pong响应
}

void WebSocketServer::handleFrameRequest(QTcpSocket *client)
{
    QJsonObject response;
    response["type"] = "frame_requested";
    response["message"] = "帧请求已收到";
    response["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);
    sendTextMessage(client, response);
}

void WebSocketServer::handleAudioRequest(QTcpSocket *client)
{
    QJsonObject response;
    response["type"] = "audio_started";
    response["message"] = "音频捕获正在运行";
    response["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);
    sendTextMessage(client, response);
}

void WebSocketServer::handleLaunchApp(QTcpSocket *client, const QJsonObject &message)
{
    QString exePath = message["exe_path"].toString();
    
    QJsonObject response;
    if (m_applicationManager && m_applicationManager->launchApplication(exePath)) {
        response["type"] = "launch_result";
        response["success"] = true;
        response["message"] = QString("应用程序启动成功: %1").arg(exePath);
    } else {
        response["type"] = "launch_result";
        response["success"] = false;
        response["message"] = "应用程序启动失败";
    }
    
    response["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);
    sendTextMessage(client, response);
}

QByteArray WebSocketServer::encodeImageToBase64(const QImage &image, int quality)
{
    QBuffer buffer;
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "JPEG", quality);
    return buffer.data().toBase64();
}

QJsonObject WebSocketServer::createFrameMessage(const QImage &image, qint64 timestamp, int frameIndex)
{
    QByteArray imageData = encodeImageToBase64(image, 80);
    
    QJsonObject message;
    message["type"] = "frame";
    message["data"] = QString::fromUtf8(imageData);
    message["format"] = "jpeg";
    message["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);
    message["sync_timestamp"] = timestamp;
    message["frame_index"] = frameIndex;
    message["size"] = imageData.size();
    
    return message;
}

QJsonObject WebSocketServer::createAudioMessage(const QByteArray &audioData, const QString &format)
{
    QByteArray audioBase64 = audioData.toBase64();
    
    QJsonObject message;
    message["type"] = "audio";
    message["data"] = QString::fromUtf8(audioBase64);
    message["format"] = format;
    message["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);
    message["size"] = audioData.size();
    
    return message;
}

QByteArray WebSocketServer::generateWebSocketKey(const QByteArray &key)
{
    QString magicString = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
    QByteArray combined = key + magicString.toUtf8();
    QByteArray hash = QCryptographicHash::hash(combined, QCryptographicHash::Sha1);
    return hash.toBase64();
}

QByteArray WebSocketServer::maskData(const QByteArray &data, const QByteArray &mask)
{
    QByteArray result = data;
    for (int i = 0; i < result.size(); ++i) {
        result[i] = static_cast<char>(result[i] ^ mask[i % 4]);
    }
    return result;
}

QByteArray WebSocketServer::unmaskData(const QByteArray &data, const QByteArray &mask)
{
    return maskData(data, mask); // 掩码和解掩码是相同的操作
}

void WebSocketServer::setTargetFps(int fps)
{
    m_targetFps = qMax(1, fps); // 确保至少1FPS
    m_frameIntervalMs = 1000 / m_targetFps;
    qDebug() << "WebSocket服务器帧率设置为:" << m_targetFps << "FPS, 间隔:" << m_frameIntervalMs << "ms";
}
